package beans;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 * @author Benjamin Gouit
 *
 */
public class QueryAnswer extends HashMap<Paragraphe, ArrayList<QueryTerme>> {

	private static final long serialVersionUID = 1L;
	
	private ArrayList<QueryTerme> qtermesListeRef;
	private ArrayList<Double> prf;
	
	public QueryAnswer (ArrayList<QueryTerme> qtermesListeRef) {
		super();
		
		this.qtermesListeRef = qtermesListeRef;
		
		this.prf = new ArrayList<Double>();
	}
	
	public ArrayList<QueryTerme> duplicateQtermesListeRef () {
		ArrayList<QueryTerme> duplicatedList = new ArrayList<QueryTerme>();
		
		for (QueryTerme qterme : qtermesListeRef)
			duplicatedList.add(qterme.duplicate());
		
		return duplicatedList;
	}
	
	public void createQanswerFile (String sDirectory, String qid, String queriesQrelDirectory) {
		
		File directory = new File(sDirectory);
		
		if (!directory.isDirectory())
			directory.mkdirs();
		
		String filepath = sDirectory + "qrel" + qid.substring(1) + ".txt";
		File qanswerFile = new File(filepath);
		if (qanswerFile.exists())
			qanswerFile.delete();
		
		try {
			qanswerFile.createNewFile();
			
			TreeMap<Double, Paragraphe> similarityHashMap = new TreeMap<Double, Paragraphe>();
			
			// Création du tableau [similarité, Paragraphe]
			System.out.println("Création du tableau [similarité, Paragraphe]");
			for (Entry<Paragraphe, ArrayList<QueryTerme>> line : this.entrySet()) {
				// Calcul de la mesure de similarité  (mesure du cosinus)
				double inner_product = 0.0;
				double somme_carré_requ = 0.0;
				double somme_carré_parag = 0.0;
				for (QueryTerme qterme : line.getValue()) {
					inner_product += qterme.getPoids()*qterme.getTfIdf();
					somme_carré_requ += qterme.getPoids()*qterme.getPoids();
					somme_carré_parag += qterme.getTfIdf()*qterme.getTfIdf();
				}
				double similarite = inner_product / (Math.sqrt(somme_carré_requ)*Math.sqrt(somme_carré_parag));
				similarityHashMap.put(similarite, line.getKey());
			}
			
			// Récupération des paragraphes pertinents
			System.out.println("Récupération des paragraphes pertinents");
			ArrayList<String> liste_pertinents = new ArrayList<String>();
			try{
				InputStream ips=new FileInputStream(queriesQrelDirectory + "qrel" + qid.substring(1) + ".txt"); 
				InputStreamReader ipsr=new InputStreamReader(ips);
				BufferedReader br=new BufferedReader(ipsr);
				String ligne;
				while ((ligne=br.readLine())!=null){
					String[] tabligne = ligne.split("\t");
					if (tabligne[2].compareTo("1") == 0) {
						liste_pertinents.add(tabligne[0]+tabligne[1]);
					}
				}
				br.close();
			}
			catch (Exception e){
				System.out.println(e.toString());
			}
			System.out.println(liste_pertinents.size());

			// Ecriture dans le fichier par ordre décroissant de similarité + calcul précision (P), rappel (R) et ? (F)
			System.out.println("Ecriture dans le fichier par ordre décroissant de similarité");
			
			FileWriter fw = new FileWriter(filepath);
			BufferedWriter bw = new BufferedWriter(fw);
			DecimalFormat df = new DecimalFormat("#.####");
			int nbParagraphePertinents = 0;
			int numLigne = 1;
			
			for (Entry<Double, Paragraphe> line : similarityHashMap.descendingMap().entrySet()) {
				// Ecriture du paragraphe concerné
				bw.write(line.getValue().getFilepath() + "\t" + line.getValue().getXpath() + "\t");
				
				// Ecriture de la similarité calculée
				bw.write(df.format(line.getKey()));
				
				// Calcul du nombre de paragraphes pertinents sélectionnés
				String paragraphepath = line.getValue().getFilepath();
				paragraphepath = paragraphepath.substring(paragraphepath.indexOf("Collection"), paragraphepath.length());
				paragraphepath += line.getValue().getXpath();
				
				if (liste_pertinents.contains(paragraphepath)) {
					nbParagraphePertinents++;
					bw.write("\tP\t");
				}
				
				// Ecriture de la précision, rappel et f
				if (numLigne == 5 || numLigne == 10 || numLigne == 25) {
					double precision = ((double)nbParagraphePertinents)/((double)numLigne);
					double rappel = ((double)nbParagraphePertinents)/((double)liste_pertinents.size());
					double f = 0.0;
					if (rappel + precision != 0.0)
						f = 2*rappel*precision / (rappel+precision);
					
					bw.write("\tP="+df.format(precision)+"; R="+df.format(rappel)+"; F="+df.format(f));
					
					prf.add(precision);
					prf.add(rappel);
					prf.add(f);
				}

				bw.write("\n");
				numLigne++;
			}
			
			bw.write("rappel = "+df.format(((double)nbParagraphePertinents)/((double)liste_pertinents.size())));
			
			bw.close();
 
			System.out.println("Fini");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	public ArrayList<Double> getPrf() {
		return this.prf;
	}
}
